﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using API.Models;
using PPG.DataAccess;
using PPG.CryptoProvider;
using System.Xml;
using System.Data;
using System.Configuration;
using System.Web;

namespace API.Controllers
{
    public class ValidateUserLoginController : ApiController
    {
        /// <summary>
        /// Intializing Helper Classes - DB Connection and Security Provider for Encrypting and Decrypting Passwords
        /// Pass in DBServerName, DBUsern
        /// ame and DBPassword from Config File for DB connections
        /// The Security helper does nto take any parameters
        /// </summary>
        DataSourceCommunicator dsComm = new DataSourceCommunicator(DataSourceCommunicator.ParamType.ServerCredentials,ConfigurationManager.AppSettings["DBServerName"].ToString(),ConfigurationManager.AppSettings["DBUserName"].ToString(),ConfigurationManager.AppSettings["DBPassword"].ToString()); 
        CryptoAgent securityHandler = new CryptoAgent();


        /// <summary>
        /// This function is the receiver of the post to the API with User credentials typed in from the website
        /// Accepts a UserAuthenticationRequest defined in the Model classes.
        /// </summary>
        /// <param name="request">This has the Username and Password entered on the website</param>
        /// <returns>UserAuthenticationResponse - Contains the outcome of the authentication, Errors if any or the User JWT token which is used to define user permissons and access</returns>
        [ActionName("ValidateUserLogin")]
        public UserAuthenticationResponse PostValidateUserLogin([FromBody]UserAuthenticationRequest request)
        {
            UserAuthenticationResponse response = new UserAuthenticationResponse();
            dsComm.AddParameter("@ParamUsername",request.Username);
            string data = dsComm.ExecuteStoredProcedure("spGetUserAuthenticationByUsername");
            XmlTextReader xReader = new XmlTextReader(data, XmlNodeType.Document, null);
            DataSet UserDataSet = new DataSet();
            UserDataSet.ReadXml(xReader);

            if(UserDataSet.Tables.Count > 0 && UserDataSet.Tables[0].Rows.Count > 0)
            {
                response.UserData = UserDataSet.Tables[0];
                DataRow dr = UserDataSet.Tables[0].Rows[0];
                response.UserFirstName = dr["FirstName"].ToString();
                response.UserLastName = dr["LastName"].ToString();
                response.LoginID = long.Parse(dr["LoginID"].ToString());
                response.PhysicianID = dr["PhysicianID"].ToString();
                if (dr["UserType"].Equals("Controller"))
                {
                    response.IsController = true;   
                }
                else
                {
                    response.IsController = false;
                }

                if (securityHandler.decryptText(dr["Password"].ToString()).Equals(request.Password))
                {
                    response.IsAuthenticated = true;
                    response.ErrorMessage = "";
                    
                    //Logging User Action
                    dsComm.AddParameter("@ParamLoginID", response.LoginID);
                    dsComm.AddParameter("@ParamActionType", "LI");
                    dsComm.AddParameter("@ParamReferenceType", "Audit");
                    dsComm.AddParameter("@ParamIPAddress", GetUserIp(Request));
                    dsComm.ExecuteNonQuery("spAddUserAction");

                    //TODO: Create JWT Token with User permission and time to live
                    CreateUserToken(dr);

                    response.UserToken = "Authenticated";
                }
                else
                {
                    response.IsAuthenticated = false;
                    response.ErrorMessage = "Invalid Username/Password combination.";

                    //Logging User Action
                    dsComm.AddParameter("@ParamLoginID", response.LoginID);
                    dsComm.AddParameter("@ParamActionType", "FL");
                    dsComm.AddParameter("@ParamReferenceType", "Audit");
                    dsComm.AddParameter("@ParamIPAddress", GetUserIp(Request));
                    dsComm.AddParameter("@ParamComment", "Incorrect Password");
                    dsComm.ExecuteNonQuery("spAddUserAction");
                }
            }
            else
            {
                response.IsAuthenticated = false;
                response.ErrorMessage = "User is not registered with the system";

                //Logging User Action
                dsComm.AddParameter("@ParamLoginID", 0);
                dsComm.AddParameter("@ParamActionType", "FL");
                dsComm.AddParameter("@ParamReferenceType", "Audit");
                dsComm.AddParameter("@ParamIPAddress", GetUserIp(Request));
                dsComm.AddParameter("@ParamComment", "Invalid User. Attempted - " + request.Username);
                dsComm.ExecuteNonQuery("spAddUserAction");
            }
            return response;
        }

        /// <summary>
        /// Options Resposen for the preflight request of a CORS Opertaions. Will be standard across various functions
        /// </summary>
        /// <returns></returns>
        public HttpResponseMessage OptionsValidateUserLogin()
        {
            var response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.OK;
            return response;
        }
        
        private string CreateUserToken(DataRow dr)
        {
            string UserToken = "";

            Guid SessionID = new Guid();



            return UserToken;
        }

        //Used to find the RequestIP
        public string GetUserIp(HttpRequestMessage request)
        {
            if (request.Properties.ContainsKey("MS_HttpContext"))
            {
                var ctx = request.Properties["MS_HttpContext"] as HttpContextBase;
                if (ctx != null)
                {
                    return ctx.Request.UserHostAddress;
                }
            }

            return null;
        }

    }
}
